package clustering;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.*;
public class Cluster_Similarity_by_GlobalProfile {
	public double CosineSimilarity_between_Clusters(ArrayList<Ngram_Profile> cluster1, ArrayList<Ngram_Profile> cluster2){
		double cosine = 0.0;
		HashMap<String,Integer> ngrams = new HashMap<String,Integer>();
		for(Ngram_Profile ngram: cluster1){
			if(!ngrams.containsKey(ngram.getNgram()))
				ngrams.put(ngram.getNgram(), ngrams.size());
		}
		for(Ngram_Profile ngram: cluster2){
			if(!ngrams.containsKey(ngram.getNgram()))
				ngrams.put(ngram.getNgram(), ngrams.size());
		}
		double cluster1_weight[] = new double[ngrams.size()];
		double cluster2_weight[] = new double[ngrams.size()];
		for(Ngram_Profile ngram: cluster1){
			int index = ngrams.get(ngram.getNgram());
			cluster1_weight[index] = ngram.getTf_idf();
		}
		for(Ngram_Profile ngram: cluster2){
			int index = ngrams.get(ngram.getNgram());
			cluster2_weight[index] = ngram.getTf_idf();
		}
		double product = 0.0, sum1 = 0.0, sum2 = 0.0;
		for(int i=0; i<ngrams.size(); i++){
			product += cluster1_weight[i]*cluster2_weight[i];
			sum1 += cluster1_weight[i]*cluster1_weight[i];
			sum2 += cluster2_weight[i]*cluster2_weight[i];
		}
		sum1 = Math.sqrt(sum1);
		sum2 = Math.sqrt(sum2);
		cosine = product / (sum1*sum2);
		return cosine>1.0? 1.0: cosine;
	}
	public void GetClusters_Similarity_File(ArrayList<ArrayList<Ngram_Profile>>clusters_profile ,String writefile){
		File f = new File(writefile);
		OutputStreamWriter write;
		try{
			write = new OutputStreamWriter(new FileOutputStream(f,false));
			BufferedWriter bw =new BufferedWriter(write);
			for(int i=0; i<clusters_profile.size(); i++)
				for(int j=i+1; j<clusters_profile.size(); j++){
					double cosine = CosineSimilarity_between_Clusters(clusters_profile.get(i),clusters_profile.get(j));
					bw.write(String.valueOf(i)+"\t"+String.valueOf(j)+"\t"+String.valueOf(cosine));
					bw.newLine();
				}
			bw.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
					
	}
	public void GetClusters_Score_File(List<Integer> cluster_size, ArrayList<ArrayList<Ngram_Profile>>clusters_profile ,String writefile, HashMap<String,Double> thresholds){
		File f = new File(writefile);
		OutputStreamWriter write;
		try{
			write = new OutputStreamWriter(new FileOutputStream(f,false));
			BufferedWriter bw =new BufferedWriter(write);
			for(int i=0; i<clusters_profile.size(); i++)
				for(int j=i+1; j<clusters_profile.size(); j++){
					double cosine = CosineSimilarity_between_Clusters(clusters_profile.get(i),clusters_profile.get(j));
					int index1 = cluster_size.get(i);
					int index2 = cluster_size.get(j);
					String key = String.valueOf(index1)+"\t"+String.valueOf(index2);
					if(index1>index2)
						key = String.valueOf(index2)+"\t"+String.valueOf(index1);
					double t = thresholds.get(key);
					double score = (cosine - t)/t;
					bw.write(String.valueOf(i)+"\t"+String.valueOf(j)+"\t"+String.valueOf(score));
					bw.newLine();
				}
			bw.close();
		}catch(IOException e)
		{
			e.printStackTrace();
		}
	}
}
